/**
 * @Author       : Hejh(3010733382@qq.com)
 * @Version      : V1.0
 * @Date         : 2024-01-21 12:29:45
 * @Description  : 抽离controller层的一些通用代码
 */
const { Op } = require('sequelize')
const Mysequelize = require('../models')
const R = require('@/models/Response')

/**
 * @author: Hejh(3010733382@qq.com)
 * @description: controller层通用的实体sort排序
 * @param {*} model
 * @param {*} errEntity
 * @param {*} idsName
 */
module.exports.sortModel = (model, errEntity, idsName) => {
  return async (ctx) => {
    let ids = ctx.request.body[idsName]
    ids = ids.map((v) => BigInt(v))
    const t = await Mysequelize.transaction()
    // 查询出实体模型对应的排序
    let sorts = await model.findAll({
      where: {
        id: {
          [Op.in]: ids
        }
      },
      attributes: ['sort']
    })

    sorts = sorts
      .map((item) => item.sort)
      .sort((a, b) => {
        return a - b
      })

    try {
      for (let i = 0; i < sorts.length; i++) {
        await model.update(
          {
            sort: sorts[i]
          },
          {
            where: {
              id: ids[i]
            },
            transaction: t
          }
        )
      }
      await t.commit()
      ctx.body = R.success()
    } catch (error) {
      await t.rollback()
      ctx.body = R.error(errEntity)
    }
  }
}

/**
 * @author: Hejh(3010733382@qq.com)
 * @description: controller层通用批量删除，对实体模型存在表其他关联的不太适用（可以进行修改让其适用性更强）
 * @param {*} model
 * @param {*} errEntity
 * @param {*} idsName
 */
module.exports.delModel = (model, errEntity, idsName) => {
  return async (ctx, option = []) => {
    const t = await Mysequelize.transaction()
    let ids = ctx.request.body[idsName]
    ids = ids.map((item) => BigInt(item))
    try {
      // 删除实体模型
      await model.destroy({
        where: {
          id: {
            [Op.in]: ids
          }
        },
        transaction: t
      })
      if (option.length) {
        for (let i = 0; i < option.length; i++) {
          // 删除实体模型对应的权限记录
          let whereCondition = {
            [option[i].idName]: {
              [Op.in]: ids
            }
          }
          if (option[i].whereCondition) {
            whereCondition = {
              ...whereCondition,
              ...option[i].whereCondition
            }
          }
          await option[i].model.destroy({
            where: whereCondition,
            transaction: t
          })
        }
      }
      await t.commit()
      ctx.body = R.success()
    } catch (error) {
      await t.rollback()
      ctx.body = R.error(errEntity)
    }
  }
}

/**
 * @author: Hejh(3010733382@qq.com)
 * @description: contrller层通用分页查询
 * @param {*} model
 */
module.exports.listModel = (model) => {
  return async (
    ctx,
    whereCondition = {},
    orderCondition = [['updateTime', 'DESC']],
    attributes = undefined,
    include = undefined
  ) => {
    const { page, pageSize } = ctx.query
    const start = (page - 1) * pageSize
    const { rows, count } = await model.findAndCountAll({
      where: whereCondition,
      attributes: attributes,
      include: include,
      offset: +start,
      limit: +pageSize,
      order: orderCondition
    })
    ctx.body = R.success({
      page,
      pageSize,
      total: count,
      pages: Math.ceil(count / pageSize),
      items: rows
    })
  }
}
